﻿using CIS.Common.Grpc.Protos;
using Google.Protobuf.WellKnownTypes;
using Grpc.Core;
using Grpc.Net.Client;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Threading.Tasks.Sources;

namespace CIS.Common.Grpc
{
    public class GrpcClient : IGrpcClient
    {
        private GrpcChannel channel;
        private GrpcService.GrpcServiceClient client;
        private ClientInfoRequest clientInfoRequest;
        private GrpcServiceBase _grpcService;
        private CancellationToken cancellationToken;
        private ClientInfo clientInfo = new ClientInfo();
        public Func<GrpcMessage, Task> OnDataRecivedAsync { get; set; }
        public Func<GrpcMessage, Task<GrpcMessage>> OnRequestAsync { get; set; }
       
        public GrpcClient(string name)
        { 
            clientInfo.ClientName = name;
            clientInfo.ClientID = Guid.NewGuid().ToString();
        }

        /// <summary>
        /// Client 端向 Server 端发 注册请求
        /// </summary>
        /// <returns></returns>
        public async Task<bool> Start()
        {
            Thread.Sleep(3000);
            channel = GrpcChannel.ForAddress("https://localhost:5000");
            client = new GrpcService.GrpcServiceClient(channel);
            RegisterRequest register = new RegisterRequest()
            {
                Client = new ClientInfoRequest()
                {
                    ClientID = clientInfo.ClientID,
                    ClientName = clientInfo.ClientName
                },
                Topic = "CCLink",
                State=true
            };
            var regisReply = client.Regist(register);
            if (regisReply != null)
                return regisReply.Result;
            else
                return false;
            
        }

        /// <summary>
        /// Client 端向 Server 端发送消息
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public async Task SendAsync(GrpcMessage message)
        {
            await client.SendAsync(message.GetData());
        }

        public Task<GrpcMessage> RequestAsync(GrpcMessage message, int timeOut = 3000)
        {
            throw new NotImplementedException();
        }

        /// <summary>
        /// 监听 Server 端发来的消息
        /// </summary>
        public void StartListen()
        {
            ClientInfoRequest request = new ClientInfoRequest()
            {
                ClientID = clientInfo.ClientID,
                ClientName = clientInfo.ClientName
            };

            Task.Run(() =>
            {
                try
                {
                    using(var grpcClient = client.Listen(request))
                    {
                        while (true)
                        {
                            var next = grpcClient.ResponseStream.MoveNext();
                            next.Wait(2000);
                            if (next.Result)
                            {
                                var result = grpcClient.ResponseStream.Current;
                                var message = new GrpcMessage(result);
                                if (message.IsRequest)
                                {
                                    OnRequestAsync.Invoke(message).ContinueWith(async (r) =>
                                    {
                                        var reply = await r;
                                        reply.Sender.ClientID = clientInfo.ClientID;
                                        reply.Sender.ClientName = clientInfo.ClientName;
                                        client.ReplyAsync(reply.GetData());
                                    });
                                }
;                            }
                        }
                    }
                }
                catch
                {

                }
            });
        }




    }
}
